package com.magold.skill.cast;

import org.andengine.engine.handler.IUpdateHandler;
import org.andengine.entity.IEntity;
import org.andengine.entity.modifier.AlphaModifier;
import org.andengine.entity.modifier.LoopEntityModifier;
import org.andengine.entity.modifier.ParallelEntityModifier;
import org.andengine.entity.modifier.RotationModifier;
import org.andengine.entity.modifier.ScaleModifier;
import org.andengine.entity.modifier.SequenceEntityModifier;
import org.andengine.entity.shape.IAreaShape;
import org.andengine.entity.sprite.Sprite;
import org.andengine.opengl.texture.region.ITiledTextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;

import com.badlogic.gdx.physics.box2d.Body;
import com.magold.sprite.CircleSprite;

public class AttacherRenderer implements MagnetAttachListener {
	private CircleSprite mRangeCircleSprite;
	private Sprite mAttacherSprite;

	public AttacherRenderer(ITiledTextureRegion pRangeTexture, VertexBufferObjectManager pVBOM) {
		this(pRangeTexture, null, pVBOM);
	}

	public AttacherRenderer(ITiledTextureRegion pRangeTexture, ITiledTextureRegion pAttacherTexture, VertexBufferObjectManager pVBOM) {
		mAttacherSprite = new Sprite(0, 0, pAttacherTexture, pVBOM);
		mAttacherSprite.registerEntityModifier(
				new LoopEntityModifier(
						new SequenceEntityModifier(
								new ParallelEntityModifier(
										new ScaleModifier(2.5f, 1.0f, 0.5f),
										new AlphaModifier(2.5f, 1.0f, 0.75f),
										new RotationModifier(2.5f, 0, 180)),
								new ParallelEntityModifier(
										new ScaleModifier(2.5f, 0.5f, 1.0f),
										new AlphaModifier(2.5f, 0.75f, 1.0f),
										new RotationModifier(2.5f, 180, 360)))));
		mAttacherSprite.setVisible(false);
		mAttacherSprite.registerUpdateHandler(new PositionUpdater(mAttacherSprite));
		
		mRangeCircleSprite = new CircleSprite(0, 0, 1, pRangeTexture, pVBOM);
		mRangeCircleSprite.setVisible(false);
		mRangeCircleSprite.registerUpdateHandler(new PositionUpdater(mRangeCircleSprite));
	}

	@Override
	public void onAttachEvent(MagnetAttacher pAttacher, Body pTarget, AttacherEvent pEvent) {
		switch (pEvent) {
		case ENTER_RANGE:
			mRangeCircleSprite.setRadius(pAttacher.getRadius());
			makeVisible(mRangeCircleSprite, pAttacher.getParent());
			break;
		case EXIT_RANGE:
			makeInvisible(mRangeCircleSprite);
			break;
		case CREATE_MAGNET:
			makeVisible(mAttacherSprite, pAttacher.getParent());
			break;
		case DESTROY_MAGNET:
			makeInvisible(mAttacherSprite);
			break;
		}
	}

	private void makeInvisible(IAreaShape pShape) {
		pShape.setVisible(false);
		IEntity p = pShape.getParent();
		p.detachChild(pShape);
	}

	private void makeVisible(IAreaShape pShape, IEntity pParent) {
		pShape.setVisible(true);
		pParent.attachChild(pShape);
		centerToParent(pShape);
	}

	private float[] mLocalCenterBuf = new float[2];
	private void centerToParent(IAreaShape pShape) {
		IEntity p = pShape.getParent();
		
		if (p == null) return;

		if (p instanceof IAreaShape) {
			mLocalCenterBuf[0] = ((IAreaShape) p).getWidth() / 2;
			mLocalCenterBuf[1] = ((IAreaShape) p).getHeight() / 2;
		} else {
			mLocalCenterBuf[0] = 0;
			mLocalCenterBuf[1] = 0;
		}
		
		float x = mLocalCenterBuf[0] - pShape.getWidth()/2;
		float y = mLocalCenterBuf[1] - pShape.getHeight()/2;
		pShape.setPosition(x, y);
	}

	private class PositionUpdater implements IUpdateHandler {
		private IAreaShape mShape;

		public PositionUpdater(IAreaShape pShape) {
			mShape = pShape;
		}

		@Override
		public void onUpdate(float pSecondsElapsed) {
			if (mShape.isVisible()) centerToParent(mShape);
		}

		@Override
		public void reset() {
		}
	}
}
